package com.hd.controller.activiti.example;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.activiti.engine.ActivitiException;
import org.activiti.engine.ActivitiObjectNotFoundException;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.hd.commons.shiro.ShiroUser;
import com.hd.controller.base.BaseController;
import com.hd.entity.activiti.BaseVO;
import com.hd.entity.activiti.CommentVO;
import com.hd.entity.activiti.ProcessType;
import com.hd.entity.activiti.example.ReceiveDocument;
import com.hd.service.activiti.ActivitiService;
import com.hd.service.activiti.ProcessInstanceEntityService;
import com.hd.service.activiti.ProcessTypeService;
import com.hd.service.activiti.UserTaskService;
import com.hd.service.activiti.example.ReceiveDocumentService;
import com.hd.util.StringUtils;
import com.hd.util.result.PageInfo;
import com.hd.util.result.Result;
@Controller
@RequestMapping("/example/receiveDocument")
public class ReceiveDocumentController extends BaseController {
	private static final String PROC_DEF_KEY = "send_doc";
	@Autowired
	private ActivitiService activitiService;
	@Autowired
	private ReceiveDocumentService receiveDocumentService;
	@Autowired
	private ProcessInstanceEntityService processInstanceEntityService;
	@Autowired
	private TaskService taskService;
	@Autowired
	private RuntimeService runtimeService;
	@Autowired
	private UserTaskService userTaskService;
	@Autowired
	private ProcessTypeService processTypeService;
	/**
	 * 请假流程管理页面
	 * @return
	 */
	@RequestMapping("/tolist")
	public String toLeavelist() {
		return "jsp/activiti/example/receive_doc/receive_doc_list";
	}
	/**
	 * 流程发起初始化页面
	 * 
	 * @param model
	 * @return
	 * @throws Exception 
	 */
	@RequestMapping("/toStart")
	public String startPage(Model model) throws Exception {
		return "jsp/activiti/example/receive_doc/receive_doc_start";
	}
	
    /**
     * 查询当前用户请假列表
     * @param page
     * @param rows
     * @param sort
     * @param order
     * @return
     */
    @RequestMapping(value="/dataGrid",method=RequestMethod.POST)
    @ResponseBody
    public Object dataGrid(ReceiveDocument receiveDocument, Integer page, Integer rows, String sort, String order) {
        PageInfo pageInfo = new PageInfo(page, rows, sort, order);
        Map<String,Object>condition=new HashMap<String,Object>();
          if(StringUtils.isNotNull(receiveDocument.getStatus())){
              condition.put("status", receiveDocument.getStatus());
          }
          if(StringUtils.isNotNull(receiveDocument.getTitle())){
              condition.put("title", receiveDocument.getTitle());
          }
          if(StringUtils.isNotNull(receiveDocument.getFromDateStart())){
              condition.put("fromDateStart", receiveDocument.getFromDateStart());
          }
          if(StringUtils.isNotNull(receiveDocument.getFromDateEnd())){
        	  condition.put("fromDateEnd", receiveDocument.getFromDateEnd());
          }
          if(StringUtils.isNotNull(receiveDocument.getProcessInstanceId())){
        	  condition.put("processInstanceId", receiveDocument.getProcessInstanceId());
          }
        condition.put("userid", getUserId());
        pageInfo.setCondition(condition);
        receiveDocumentService.selectDataGrid(pageInfo);
        return pageInfo;
    }

	/**
	 * 暂存
	 * @param leave
	 * @return
	 */
	@ResponseBody
	@RequestMapping("/tempStorage")
    public Object tempStorage(ReceiveDocument receiveDocument){
		String title = "";
		receiveDocument.setStatus(BaseVO.TEMP_STOAGE);// 暂存
		// 保存数据
		receiveDocument.setPrevUserid(getUserId());
		ProcessType processType = processTypeService.getByKey(PROC_DEF_KEY);
		String businessid="";
		if(processType!=null) {
			businessid=processType.getId();
			receiveDocument.setBusinessType_(processType.getName());
			receiveDocument.setBusinessKey_(PROC_DEF_KEY);
		}else {
			receiveDocument.setBusinessType_("发文流程");
			receiveDocument.setBusinessKey_(PROC_DEF_KEY);
		}
		receiveDocument.setUserid_(getUserId());
		receiveDocument.setTitle_(title);
		receiveDocument.setUserName_(getStaffName());
		receiveDocumentService.save(receiveDocument);
		logger.info("暂存");
		return renderSuccess();
	}

	/**
	 * 提交申请
	 * @param id
	 * @return
	 */
	@ResponseBody
	@RequestMapping("/submitProcessInstance")
	public Object submitProcessInstance(String id){
		ReceiveDocument receiveDocument=receiveDocumentService.get(id);
		Result result = new Result();
		String title = "";
		// 启动流程
		try {
			receiveDocument.setStatus(BaseVO.PENDING);// 审批中
			// 保存数据
			receiveDocument.setPrevUserid(getUserId());
			ProcessType processType = processTypeService.getByKey(PROC_DEF_KEY);
			String businessid="";
			String processTitle="发文流程";
			if(processType!=null) {
				processTitle=processType.getName();
				businessid=processType.getId();
				receiveDocument.setBusinessType_(processType.getName());
				receiveDocument.setBusinessKey_(PROC_DEF_KEY);
			}else {
				receiveDocument.setBusinessType_("发文流程");
				receiveDocument.setBusinessKey_(PROC_DEF_KEY);
			}
			receiveDocument.setUserid_(getUserId());
			receiveDocument.setTitle_(title);
			receiveDocument.setUserName_(getStaffName());
			receiveDocumentService.update(receiveDocument);
			String processInstanceId=receiveDocumentService.startProcessInstance(PROC_DEF_KEY,receiveDocument);
			com.hd.entity.activiti.ProcessInstanceEntity pi = new com.hd.entity.activiti.ProcessInstanceEntity();
			pi.setProcessInstanceId(processInstanceId);
			pi.setStartTime(new Date());
			pi.setStatus(com.hd.entity.activiti.ProcessInstanceEntity.RUN_STATUS);
			pi.setTitle(title);
			pi.setUserid(receiveDocument.getUserid());
			pi.setUserName(receiveDocument.getUserName());
			pi.setBusinessKey(PROC_DEF_KEY);
			pi.setBusinessType(processTitle);
			pi.setBusinessId(businessid);
			processInstanceEntityService.save(pi);
			result.setSuccess(Boolean.TRUE);
			result.setMsg("请假流程已启动，流程ID：" + processInstanceId);
			logger.info("processInstanceId: " + processInstanceId);
		} catch (ActivitiException e) {
			result.setSuccess(Boolean.FALSE);
			if (e.getMessage().indexOf("no processes deployed with key") != -1) {
				logger.warn("没有部署流程!", e);
				result.setMsg("没有部署流程，请联系系统管理员，在[流程定义]中部署相应流程文件！");
			} else {
				logger.error("启动请假流程失败：", e);
				result.setMsg("启动请假流程失败，系统内部错误！");
			}
			throw e;
		} catch (Exception e) {
			logger.error("启动请假流程失败：", e);
			result.setSuccess(Boolean.FALSE);
			result.setMsg("启动请假流程失败，系统内部错误！");
			throw e;
		}
		return result;
	}
    
	/**
	 * 启动流程
	 * 
	 * @param leave
	 * @return
	 */
    @ResponseBody
	@RequestMapping("/startProcessInstance")
	public Object startProcessInstance(ReceiveDocument receiveDocument) {
		Result result = new Result();
		String title = "";
		// 启动流程
		try {
			receiveDocument.setStatus(BaseVO.PENDING);// 审批中
			// 保存数据
			receiveDocument.setPrevUserid(getUserId());
			ProcessType processType = processTypeService.getByKey(PROC_DEF_KEY);
			String processTitle="发文流程";
			String businessid="";
			if(processType!=null) {
				processTitle=processType.getName();
				businessid=processType.getId();
				receiveDocument.setBusinessType_(processType.getName());
				receiveDocument.setBusinessKey_(PROC_DEF_KEY);
			}else {
				receiveDocument.setBusinessType_("发文流程");
				receiveDocument.setBusinessKey_(PROC_DEF_KEY);
			}
			receiveDocument.setUserid_(getUserId());
			receiveDocument.setTitle_(title);
			receiveDocument.setUserName_(getStaffName());
			receiveDocumentService.save(receiveDocument);
			String processInstanceId=receiveDocumentService.startProcessInstance(PROC_DEF_KEY,receiveDocument);
			com.hd.entity.activiti.ProcessInstanceEntity pi = new com.hd.entity.activiti.ProcessInstanceEntity();
			pi.setProcessInstanceId(processInstanceId);
			pi.setStartTime(new Date());
			pi.setStatus(com.hd.entity.activiti.ProcessInstanceEntity.RUN_STATUS);
			pi.setTitle(title);
			pi.setUserid(receiveDocument.getUserid());
			pi.setUserName(receiveDocument.getUserName());
			pi.setBusinessKey(PROC_DEF_KEY);
			pi.setBusinessType(processTitle);
			pi.setBusinessId(businessid);
			processInstanceEntityService.save(pi);
			result.setSuccess(Boolean.TRUE);
			result.setMsg("请假流程已启动，流程ID：" + processInstanceId);
			logger.info("processInstanceId: " + processInstanceId);
		} catch (ActivitiException e) {
			result.setSuccess(Boolean.FALSE);
			if (e.getMessage().indexOf("no processes deployed with key") != -1) {
				logger.warn("没有部署流程!", e);
				result.setMsg("没有部署流程，请联系系统管理员，在[流程定义]中部署相应流程文件！");
			} else {
				logger.error("启动请假流程失败：", e);
				result.setMsg("启动请假流程失败，系统内部错误！");
			}
			throw e;
		} catch (Exception e) {
			logger.error("启动请假流程失败：", e);
			result.setSuccess(Boolean.FALSE);
			result.setMsg("启动请假流程失败，系统内部错误！");
			throw e;
		}
		return result;
	}
	
	/**
	 * 跳转到审批页面
	 * @param taskId 任务id
	 * @param model
	 * @return
	 */
	@RequestMapping("/toApproval/{taskId}")
	public String toApproval(@PathVariable("taskId")String taskId,Model model) {
		//查询任务
		Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
		System.out.println(task.getProcessInstanceId());
		//查询流程实例
		String processInstanceId=task.getProcessInstanceId();
		ProcessInstance pi=runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId)
				.singleResult();
		//查询出实体
		ReceiveDocument receiveDocument=(ReceiveDocument) this.runtimeService.getVariable(pi.getId(), "entity");
		receiveDocument.setProcessInstanceId(processInstanceId);
		receiveDocument.setTask(task);
		//查询出评论
		String taskDefinitionKey=task.getTaskDefinitionKey();
		List<CommentVO>comments=activitiService.getCommentsByProcessInstanceId(processInstanceId);
		//业务处理,根据taskDefinitionKey跳转页面
		String result="";
		//#if ...else
//		 if("modifyApply".equals(taskDefinitionKey)){
//	          result = "jsp/activiti/example/leave/modify_leave";
//	     }else{
//	          result = "jsp/activiti/example/leave/audit_leave";
//	     }
		 
		 result = "jsp/activiti/example/receive_doc/approval_receive_doc";
		//任务执行人
		String assigneeOrCandidateUser=(String) activitiService.findTodoTaskAssigneeOrCandidateUsers(processInstanceId)
											.get("userNames");
		model.addAttribute("assigneeOrCandidateUser", assigneeOrCandidateUser);
		model.addAttribute("receiveDocument", receiveDocument);
		model.addAttribute("comments", comments);
		model.addAttribute("taskId", taskId);
		model.addAttribute("procDefId", pi.getProcessDefinitionId());
		model.addAttribute("taskDefKey", task.getTaskDefinitionKey());
		return result;
	}
	
	
	
	/**
	 * 完成任务
	 * @param taskId 任务id
	 * @param content 审批意见
	 * @param id 请假申请id
	 * @param completeFlag 审批标志：同意、驳回
	 * @return
	 */
	@ResponseBody
	@RequestMapping("/completeTask/{taskId}")
	public Object completeTask(@PathVariable("taskId")String taskId,
		String content,String id,Boolean completeFlag) {
		ShiroUser shiroUser=getShiroUser();
		Result result=new Result();
		 try {
	            ReceiveDocument receiveDocument = this.receiveDocumentService.get(id);
	            ReceiveDocument bean = (ReceiveDocument) this.runtimeService.getVariable(receiveDocument.getProcessInstanceId(), "entity");
	            Map<String, Object> variables = new HashMap<String, Object>();
	            variables.put("isPass", completeFlag);
	            if(!completeFlag){
	            	bean.setTitle_("【"+bean.getTitle()+"】的流程审批失败,需修改后重新提交！");
	            	receiveDocument.setStatus_(BaseVO.APPROVAL_ADJUST);
	            	receiveDocument.setStatus(BaseVO.APPROVAL_ADJUST);
	                variables.put("entity", bean);
	                variables.put("prevUserid", getUserId());
	            }
	            if(!completeFlag) {
	            	if(!StringUtils.isNotNull(content)) {
	            		content="不同意";
	            	 }
	            }else {
	            	if(!StringUtils.isNotNull(content)) {
	            		content="同意";
	            	 }
	            }
	            // 完成任务
	            this.activitiService.completeTask(taskId, content, shiroUser.getId(), variables);
	            if(completeFlag){
	                //此处需要修改，不能根据人来判断审批是否结束。应该根据流程实例id(processInstanceId)来判定。
	                //判断指定ID的实例是否存在，如果结果为空，则代表流程结束，实例已被删除(移到历史库中)
	                ProcessInstance pi = this.runtimeService.createProcessInstanceQuery().processInstanceId(receiveDocument.getProcessInstanceId()).singleResult();
	                if(pi==null){
	                	receiveDocument.setStatus(BaseVO.APPROVAL_SUCCESS);
	                    //设置流程完成
	                    com.hd.entity.activiti.ProcessInstanceEntity instance = processInstanceEntityService.get(receiveDocument.getProcessInstanceId());
	                    instance.setEndTime(new Date());
	                    instance.setStatus(BaseVO.APPROVAL_SUCCESS);
	                    processInstanceEntityService.update(instance);
	                }
	            }

	            this.receiveDocumentService.update(receiveDocument);
	            result.setSuccess(Boolean.TRUE);
	            result.setMsg("任务办理完成！");
	        } catch (ActivitiObjectNotFoundException e) {
	            result.setSuccess(Boolean.FALSE);
	            result.setMsg("此任务不存在，请联系管理员！");
	            throw e;
	        } catch (ActivitiException e) {
	            result.setSuccess(Boolean.FALSE);
	            result.setMsg("此任务正在协办，您不能办理此任务！");
	            throw e;
	        } catch (Exception e) {
	            result.setSuccess(Boolean.FALSE);
	            result.setMsg("任务办理失败，请联系管理员！");
	            throw e;
	        }
	        return result;
	}
	
	
    
    @RequestMapping("/viewleaveinfo/{processInstanceId}")
    public String viewleaveinfo(@PathVariable("processInstanceId")String processInstanceId,Model model) {
    	ReceiveDocument receiveDocument = receiveDocumentService.getByProcessInstanceId(processInstanceId);
    	model.addAttribute("receiveDocument", receiveDocument);
    	List<CommentVO>comments=activitiService.getCommentsByProcessInstanceId(processInstanceId);
    	model.addAttribute("comments", comments);
    	return "jsp/activiti/example/receive_doc/receive_doc_view";
    }
    /**
     * 作废
     * @param processInstanceId
     * @return
     */
    @RequestMapping("/cancel")
    @ResponseBody
    public Object cancel(String processInstanceId) {
    	receiveDocumentService.deleteReceiveDocumentProcess(processInstanceId);
    	return renderSuccess("作废成功！");
    }


    @ResponseBody
	@RequestMapping("delete")
	public Object delete(String id){
    	receiveDocumentService.delete(id);
    	return renderSuccess("删除成功！");
	}

	@RequestMapping("/editPage")
	public String editPage(String id,Model model){
		ReceiveDocument receiveDocument=receiveDocumentService.get(id);
		model.addAttribute("receiveDocument",receiveDocument);
		return "jsp/activiti/example/receive_doc/receive_doc_edit";
	}

	@ResponseBody
	@RequestMapping("/edit")
	public Object edit(ReceiveDocument receiveDocument){
		receiveDocument.setStatus(BaseVO.TEMP_STOAGE);
		receiveDocumentService.update(receiveDocument);
		return renderSuccess("编辑成功！");
	}
}
